package a_airwar;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;


public class JFrameMain extends JPanel {
    //静态成员变量
    public static BufferedImage bigplane;
    public static BufferedImage airplane;
    public static BufferedImage bee;
    public static BufferedImage hero1;
    public static BufferedImage hero0;
    public static BufferedImage bullet;
    public static BufferedImage pause;
    public static BufferedImage start;
    public static BufferedImage background;
    public static BufferedImage gameover;
    public static int Height = 700;
    public static int Width = 400;

    public final int START = 0;    //启动状态
    public final int RUNNING = 1;  //运行状态
    public final int PAUSE = 2;    //停止状态
    public final int GAME_OVER = 3;//结束状态
    private int state = START;  //当前状态

    //在加载类之前需要将所有的图片信息加载到JVM中
    static {
        try {
            background = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/background.png"));
            bigplane = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/bigplane.png"));
            airplane = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/airplane.png"));
            bee = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/bee.png"));
            hero1 = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/hero0.png"));
            hero0 = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/hero1.png"));
            bullet = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/bullet.png"));
            pause = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/pause.png"));
            start = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/start.png"));
            gameover = ImageIO.read(JFrameMain.class.getResourceAsStream("pic/gameover.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    Hero hero = new Hero();
    ArrayList<FlyObj> flyings = new ArrayList();
    ArrayList<Bullet> bullets = new ArrayList();


    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(background, 0, 0, null);
        g.drawImage(hero.getImage(), hero.getX(), hero.getY(), null);
        drawImageFlying(g);
        drawImageBullet(g);
        judgmentOfState(g);
        scoreAndLife(g);

    }


    Timer timer = new Timer();

    public void action() {

        /*schedule-行程表
         * 参数一：要做的定时重复的事
         * 参数二：定时器第一次开始的时间
         * 参数三：间隔时间*/
        //创建一个子类继承抽象类
        /*class MyTimerTask extends TimerTask{
        @override
        public void run(){}
        }*/

        timer.schedule(new TimerTask() //匿名内部类
        {
            @Override
            public void run() {
                if (state == RUNNING) {
                    hero.move();
                    //*1.生成很多个飞行物
                    createFlying();
                    //* 2.所有飞行物的移动
                    flyingMove();
                    //* 3.判断飞行物的越界问题，删除已经越界的飞行物
                    deleteFlying();
                    //* 4.生成很多子弹
                    createShootMethod();
                    //* 5.所有的子弹移动
                    bulletMove();
                    //* 6.判断子弹的越界问题
                    deleteBullet();
                    //飞行物与子弹碰撞
                    bangAction();
                    //飞机与敌机碰撞
                    collision();
                    repaint();

                }
            }
        }, 1000, 20);

        /*添加鼠标监听
         * 1.创建实现类实现接口
         * 2.匿名内部类*/
        MouseAdapter mouseAdapter = new MouseAdapter() {
            //鼠标移动
            public void mouseMoved(MouseEvent e) {
                if (state == RUNNING) {
                    hero.mouseMove(e.getX(), e.getY());
                  /*  int mousex = e.getX() - hero0.getWidth() / 2;
                    int mousey = e.getY() - hero0.getHeight() / 2;
                    hero.setX(mousex);
                    hero.setY(mousey);*/
                }
                repaint();
            }

            public void mouseClicked(MouseEvent e) {
                if (state == START) {
                    state = RUNNING;
                } else if (state == GAME_OVER) {
                    state = START;
                    hero.setLife(3);
                }
                repaint();
            }

            //鼠标移入事件
            public void mouseEntered(MouseEvent e) {
                if (state == PAUSE) {
                    state = RUNNING;
                }
                repaint();
            }

            //鼠标移出事件
            public void mouseExited(MouseEvent e) {
                if (state == RUNNING) {
                    state = PAUSE;
                }
                repaint();
            }

        };
        this.addMouseListener(mouseAdapter); //处理鼠标操作事件
        this.addMouseMotionListener(mouseAdapter); //处理鼠标滑动事件
    }


    //创建
    //计数
    private int flyindex = 0;

    private void createFlying() {
        flyindex++;
        if (flyindex % 15 == 0) {
            int random = (int) (Math.random() * 20);
            //创建父类变量
            FlyObj flyObj;
            if (random == 10) {
                flyObj = new Bee();
            } else if (random == 1) {
                flyObj = new Bigplane();
            } else {
                flyObj = new Airplane();
            }
            flyings.add(flyObj);
        }
    }

    //删除
    private void deleteFlying() {
        for (int i = 0; i < flyings.size(); i++) {
            //如果飞行物的y>=JFrameMain.Height，删除;
            FlyObj flyObj = flyings.get(i);
            if (flyObj.getY() >= JFrameMain.Height) {
                flyings.remove(i);
                i--;
            }

        }
    }

    //飞行物移动
    private void flyingMove() {
        for (int i = 0; i < flyings.size(); i++) {
            FlyObj flyObj = flyings.get(i);
            flyObj.move();
        }
    }

    private void createShootMethod() {
        flyindex++;
        /*界面存在很多子弹——>ArrayList.add()
         * 存储的子弹一开始是从英雄机发射出来的*/
        if (flyindex % 20 == 0) {
            Bullet[] shoot = hero.shoot();
            for (int i = 0; i < shoot.length; i++) {
                bullets.add(shoot[i]);
            }
        }
    }

    private void bulletMove() {
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            bullet.move();
        }
    }

    private void deleteBullet() {
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            if (bullet.getY() <= 0) {
                bullets.remove(i);
                i--;
            }
        }
    }

    //绘画
    private void drawImageFlying(Graphics g) {
        for (int i = 0; i < flyings.size(); i++) {
            //获得飞行物
            FlyObj flyObj = flyings.get(i);
            g.drawImage(flyObj.getImage(), flyObj.getX(), flyObj.getY(), null);
        }
    }

    private void drawImageBullet(Graphics g) {
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bs = bullets.get(i);
            g.drawImage(bs.getImage(), bs.getX(), bs.getY(), null);
        }
    }

    private void judgmentOfState(Graphics g) {
        if (state == START) {
            g.drawImage(start, 0, 0, null);
        } else if (state == PAUSE) {
            g.drawImage(pause, 0, 0, null);
        }

        if (state == GAME_OVER)
            g.drawImage(gameover, 0, 0, null);

    }

    private void scoreAndLife(Graphics g) {
        Color color = new Color(0xD91B1B);
        g.setColor(color);
        Font font = new Font("宋体", Font.BOLD, 20);
        g.setFont(font);
        g.drawString("Score:" + hero.getScore(), 0, 20);
        g.drawString("Life:" + hero.getLife(), 0, 50);


    }

    //飞机与敌机碰撞
    private void collision() {
        for (int i = 0; i < flyings.size(); i++) {
            //获取飞行物 get();
            FlyObj flyObj = flyings.get(i);
            if (hero.getX() >= flyObj.getX()
                    && hero.getX() <= flyObj.getX() + flyObj.getWidth()
                    && hero.getY() >= flyObj.getY()
                    && hero.getY() <= flyObj.getY() + flyObj.getHeight()) {
                hero.reduceLife();
                flyings.remove(i);
                i--;
                if (hero.getLife() <= 0) {
                    hero.setScore(0);  //清空数据
                    hero = new Hero();
                    flyings = new ArrayList<>();
                    state = GAME_OVER;
                }
            }
        }
    }


    //6.1飞行物和子弹的碰撞 - 碰撞
    private void bangAction() {
        //获得每颗子弹和每个飞行物
        for (int i = 0; i < flyings.size(); i++) {
            for (int j = 0; j < bullets.size(); j++) {
                //获得子弹
                Bullet bullet = bullets.get(j);
                //获得每个飞行物
                FlyObj flyObj = flyings.get(i);
                //判断:如果碰撞上了,飞行物(life==0)消失,子弹消失
                if (bullet.getX() <= flyObj.getX() + flyObj.getWidth()
                        && bullet.getX() >= flyObj.getX()
                        && bullet.getY() >= flyObj.getY()
                        && bullet.getY() <= flyObj.getY() + flyObj.getHeight()) {

                    //fly.setLife(fly.getLife() - 1);//封装在飞行物中的方法
                    flyObj.reduceLife();//调用父类中的方法
                    if (flyObj.getLife() == 0) {
                        //添加分数: 大敌机 + 小敌机 -> 添加到Hero上
                        if (flyObj instanceof Enemy) {
                            Enemy enemy = (Enemy) flyObj;//做强转
                            //hero.setScore(hero.getScore() + enemy.getScore());
                            hero.addScore(enemy.getScore());
                        }
                        //添加奖励: 有可能火力加成,生命值加成
                        //大敌机和小蜜蜂
                        if (flyObj instanceof Award) {//向下转型
                            Award award = (Award) flyObj;
                            int type = award.getType();
                            switch (type) {
                                case Award.DOUBLE_FILE:
                                    hero.doubleFire();
                                    break;
                                case Award.LIFE:
                                    hero.addLife();
                                    break;
                            }
                        }

                        flyings.remove(i);
                        i--;
                        break;
                    }
                    //子弹消失
                    bullets.remove(j);

                }
            }
        }
    }

    public static void main(String[] args) {
        JFrame window = new JFrame("飞机大战");
        JFrameMain jPanel = new JFrameMain();
        //添加画布
        window.add(jPanel);
        //设置大小
        window.setSize(Width, Height);
        //创建线程
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //窗口显示
        window.setVisible(true);
        jPanel.action();
    }
}
